/*
 * Copyright (c) 2011-2014, fortiss GmbH.
 * Licensed under the Apache License, Version 2.0.
 *
 * Use, modification and distribution are subject to the terms specified
 * in the accompanying license file LICENSE.txt located at the root directory
 * of this software distribution. A copy is available at
 * http://chromosome.fortiss.org/.
 *
 * This file is part of CHROMOSOME.
 *
 * $Id: detectDevicesFunction.c 7805 2014-03-13 09:54:35Z geisinger $
 */

/**
 * \file
 *         Source file for function detectDevices in component detector.
 *
 * \author
 *         This file has been generated by the CHROMOSOME Modeling Tool (XMT)
 *         (fortiss GmbH).
 */

/******************************************************************************/
/***   Includes                                                             ***/
/******************************************************************************/
#include "detector/adv/detector/include/detectDevicesFunction.h"

#include "detector/adv/detector/include/detectDevicesFunctionWrapper.h"
#include "detector/adv/detector/include/detectorComponent.h"
#include "detector/adv/detector/include/detectorComponentWrapper.h"
#include "detector/adv/detector/include/detectorManifest.h"

#include "xme/core/logUtils.h"

// PROTECTED REGION ID(DETECTOR_ADV_DETECTOR_DETECTDEVICESFUNCTION_C_INCLUDES) ENABLED START
#include "xme/core/nodeManager/include/componentRepositoryBuilder.h"
#include "xme/core/plugAndPlay/include/plugAndPlayClient.h"

#include "xme/hal/include/time.h"

#include "detector/adv/device/include/deviceManifest.h"
#include "detector/adv/device/include/deviceComponentWrapper.h"
// PROTECTED REGION END

/******************************************************************************/
/***   Definitions                                                          ***/
/******************************************************************************/

// PROTECTED REGION ID(DETECTOR_ADV_DETECTOR_DETECTDEVICESFUNCTION_C_DEFINITIONS) ENABLED START
// PROTECTED REGION END

/******************************************************************************/
/***   Variables                                                            ***/
/******************************************************************************/

// PROTECTED REGION ID(DETECTOR_ADV_DETECTOR_DETECTDEVICESFUNCTION_C_VARIABLES) ENABLED START
// PROTECTED REGION END

/******************************************************************************/
/***   Prototypes                                                           ***/
/******************************************************************************/

// PROTECTED REGION ID(DETECTOR_ADV_DETECTOR_DETECTDEVICESFUNCTION_C_PROTOTYPES) ENABLED START
// PROTECTED REGION END

/******************************************************************************/
/***   Implementation                                                       ***/
/******************************************************************************/
xme_status_t
detector_adv_detector_detectDevicesFunction_init
(
    detector_adv_detector_detectorComponent_config_t* const componentConfig
)
{
    // PROTECTED REGION ID(DETECTOR_ADV_DETECTOR_DETECTDEVICESFUNCTION_INITIALIZE_C) ENABLED START
    XME_UNUSED_PARAMETER(componentConfig);

    return XME_STATUS_SUCCESS;
    // PROTECTED REGION END
}

void
detector_adv_detector_detectDevicesFunction_step
(
    detector_adv_detector_detectorComponent_config_t* const componentConfig
)
{
    
    {
        // PROTECTED REGION ID(DETECTOR_ADV_DETECTOR_DETECTDEVICESFUNCTION_STEP_C) ENABLED START
        static xme_core_nodeMgr_compRep_componentHandle_t cameraComponentHandle = XME_CORE_NODEMGR_COMPREP_INVALID_HANDLE;
        static xme_core_nodeMgr_compRep_componentHandle_t usbStickComponentHandle = XME_CORE_NODEMGR_COMPREP_INVALID_HANDLE;

        switch (componentConfig->state)
        {
            case CREATE_DEVICE_CAMERA:
                {
                    xme_status_t cameraStatus;

                    xme_core_nodeMgr_compRep_componentBuilder_t* builder =
                        xme_core_nodeMgr_compRep_createBuilder
                        (
                            XME_CORE_NODE_LOCAL_NODE_ID,
                            (xme_core_componentType_t)XME_CORE_COMPONENT_TYPE_DEVICE
                        );
                    xme_core_nodeMgr_compRep_builderSetInitializationString(builder, "Camera");
                    xme_core_nodeMgr_compRep_builderSetExecutionPeriod(builder, DETECTOR_ADV_DEVICE_DEVICECOMPONENTWRAPPER_FUNCTION_OPERATE, xme_hal_time_timeIntervalFromMilliseconds(700ull));
                    cameraStatus = xme_core_nodeMgr_compRep_build(builder, &cameraComponentHandle);
                    XME_ASSERT_NORVAL(XME_STATUS_SUCCESS == cameraStatus);
                    cameraStatus = xme_core_pnp_pnpClient_plugInNewComponent(cameraComponentHandle);
                    if (XME_STATUS_SUCCESS != cameraStatus)
                    {
                        XME_LOG
                        (
                            XME_LOG_ERROR,
                            "[Detector] Cannot send the Camera component connection request for handle %d on PnPClient. Returned status=%d.\n",
                            cameraComponentHandle,
                            cameraStatus
                        );
                    }
                    else
                    {
                        XME_LOG
                        (
                            XME_LOG_ALWAYS,
                            "[Detector] Camera connection request with the component handle %d successfully sent to PnPClient.\n",
                            cameraComponentHandle
                        );
                    }
                }

                componentConfig->state = CREATE_DEVICE_USB_STICK;
                break;

            case CREATE_DEVICE_USB_STICK:
                {
                    xme_status_t usbStatus;

                    xme_core_nodeMgr_compRep_componentBuilder_t* builder =
                        xme_core_nodeMgr_compRep_createBuilder
                        (
                            XME_CORE_NODE_LOCAL_NODE_ID,
                            (xme_core_componentType_t)XME_CORE_COMPONENT_TYPE_DEVICE
                        );
                    xme_core_nodeMgr_compRep_builderSetInitializationString(builder, "USB Stick");
                    xme_core_nodeMgr_compRep_builderSetExecutionPeriod(builder, DETECTOR_ADV_DEVICE_DEVICECOMPONENTWRAPPER_FUNCTION_OPERATE, xme_hal_time_timeIntervalFromMilliseconds(700ull));
                    usbStatus = xme_core_nodeMgr_compRep_build(builder, &usbStickComponentHandle);
                    XME_ASSERT_NORVAL(XME_STATUS_SUCCESS == usbStatus);
                    usbStatus = xme_core_pnp_pnpClient_plugInNewComponent(usbStickComponentHandle);
                    if (XME_STATUS_SUCCESS != usbStatus)
                    {
                        XME_LOG
                        (
                            XME_LOG_ERROR,
                            "[Detector] Cannot send the USB stick component connection request for handle %d on PnPClient. Returned status=%d.\n",
                            usbStickComponentHandle,
                            usbStatus
                        );
                    }
                    else
                    {
                        XME_LOG
                        (
                            XME_LOG_ALWAYS,
                            "[Detector] USB Stick connection request with the component handle %d successfully sent to PnPClient.\n",
                            usbStickComponentHandle
                        );
                    }

                }

                componentConfig->state = WAIT_BEFORE_DESTROY;
                break;

            case WAIT_BEFORE_DESTROY:
                {
                    static int i = 0;

                    i = (i + 1) % 3;
                    if (0 == i)
                    {
                        componentConfig->state = DESTROY_DEVICE_CAMERA;
                    }
                }
                break;

            case DESTROY_DEVICE_CAMERA:
                {
                    xme_status_t cameraStatus = xme_core_pnp_pnpClient_destroyComponentOnThisNode(cameraComponentHandle);
                    if (XME_STATUS_SUCCESS != cameraStatus)
                    {
                        XME_LOG
                        (
                            XME_LOG_ERROR,
                            "[Detector] Cannot send a Camera remove component request for handle %d to PnPClient. Returned status=%d.\n",
                            cameraComponentHandle,
                            cameraStatus
                        );
                    }
                    else
                    {
                        XME_LOG
                        (
                            XME_LOG_ALWAYS,
                            "[Detector] Camera remove request with the component handle %d successfully sent to PnPClient. \n",
                            cameraComponentHandle
                        );
                    }
                    cameraComponentHandle = XME_CORE_NODEMGR_COMPREP_INVALID_HANDLE;

                    componentConfig->state = DESTROY_DEVICE_USB_STICK;
                    break;
                }

            case DESTROY_DEVICE_USB_STICK:
                {
                    xme_status_t usbStatus = xme_core_pnp_pnpClient_destroyComponentOnThisNode(usbStickComponentHandle);
                    if (XME_STATUS_SUCCESS != usbStatus)
                    {
                        XME_LOG
                        (
                            XME_LOG_ERROR,
                            "[Detector] Cannot send a USB Stick remove component request for handle %d to PnPClient. Returned status=%d.\n",
                            usbStickComponentHandle
                        );
                    }
                    else
                    {
                        XME_LOG
                        (
                            XME_LOG_ALWAYS,
                            "[Detector] USB Stick remove request with the component handle %d successfully sent to PnPClient.\n",
                            usbStickComponentHandle
                        );
                    }
                    usbStickComponentHandle = XME_CORE_NODEMGR_COMPREP_INVALID_HANDLE;

                    componentConfig->state = CREATE_DEVICE_CAMERA;
                    break;
                }
        }
        // PROTECTED REGION END
    }
    
    {
        // PROTECTED REGION ID(DETECTOR_ADV_DETECTOR_DETECTDEVICESFUNCTION_STEP_2_C) ENABLED START
        // PROTECTED REGION END
    }
}

void
detector_adv_detector_detectDevicesFunction_fini
(
    detector_adv_detector_detectorComponent_config_t* const componentConfig
)
{
    // PROTECTED REGION ID(DETECTOR_ADV_DETECTOR_DETECTDEVICESFUNCTION_TERMINATE_C) ENABLED START
    XME_UNUSED_PARAMETER(componentConfig);
    // PROTECTED REGION END
}

// PROTECTED REGION ID(DETECTOR_ADV_DETECTOR_DETECTDEVICESFUNCTION_IMPLEMENTATION_C) ENABLED START
// PROTECTED REGION END
